package org.dxy.trigger.http.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dxy.api.dto.RegisterEquipmentRequestDto;
import org.dxy.api.dto.UpdateEquipmentRequestDto;
import org.dxy.api.response.R;
import org.dxy.domain.port.CommandHandler;
import org.dxy.domain.command.equipment.DeleteEquipmentCommand;
import org.dxy.domain.command.equipment.RegisterEquipmentCommand;
import org.dxy.infrastructure.persistent.db.mybatispuls.po.query.EquipmentBasicViewPo;
import org.dxy.infrastructure.persistent.db.mybatispuls.service.EquipmentBasicViewService;
import org.dxy.trigger.http.service.EquipmentApplicationService;
import org.dxy.types.common.CommandResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @ description:
 * @ author: dxy
 * @ createTime: 2025/7/17 22:40
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class EquipmentApplicationServiceImpl implements EquipmentApplicationService {
    private final CommandHandler<RegisterEquipmentCommand, Long> registerCommandHandler;
    private final CommandHandler<DeleteEquipmentCommand, Void> deleteCommandHandler;
    private final EquipmentBasicViewService equipmentBasicViewService;

    @Override
    @Transactional
    public R<Void> register(RegisterEquipmentRequestDto dto) {
        log.info("开始注册设备，请求参数：{}", dto);

        // 构造领域命令
        RegisterEquipmentCommand command = RegisterEquipmentCommand.builder()
                .equipmentType(dto.getEquipmentType())
                .serialNumber(dto.getSerialNumber())
                .build();

        // 执行领域逻辑
        CommandResult<Long> result = registerCommandHandler.handle(command);
        if (!result.success()) {
            log.warn("设备注册失败，原因：{}", result.msg());
            return R.fail(null, result.msg());
        }

        Long equipmentId = result.data();
        log.info("设备注册成功，设备ID={}", equipmentId);

        // 构造并保存读模型
        EquipmentBasicViewPo viewEntity = EquipmentBasicViewPo.builder()
                .id(equipmentId)
                .equipmentName(dto.getEquipmentName())
                .manufacturer(dto.getManufacturer())
                .modelNumber(dto.getModelNumber())
                .serialNumber(dto.getSerialNumber())
                .location(dto.getLocation())
                .build();

        equipmentBasicViewService.save(viewEntity);
        log.info("读模型保存成功，设备ID={}", equipmentId);

        // 注意：事件发布由 registerCommandHandler.handle 内部触发，但由于 @Transactional，
        // 事件发布（如通过 Spring 的事件机制）会在事务提交后执行

        return R.ok("注册设备成功");
    }

    @Override
    public R<Page<EquipmentBasicViewPo>> list(Page<EquipmentBasicViewPo> page, EquipmentBasicViewPo query) {
        LambdaQueryWrapper<EquipmentBasicViewPo> wrapper = Wrappers.lambdaQuery();

        if (query.getEquipmentName() != null) {
            wrapper.like(EquipmentBasicViewPo::getEquipmentName, query.getEquipmentName());
        }
        if (query.getEquipmentType() != null) {
            wrapper.eq(EquipmentBasicViewPo::getEquipmentType, query.getEquipmentType());
        }
        if (query.getStatus() != null) {
            wrapper.eq(EquipmentBasicViewPo::getStatus, query.getStatus());
        }

        Page<EquipmentBasicViewPo> resultPage = equipmentBasicViewService.page(page, wrapper);
        return R.ok(resultPage);
    }

    @Override
    @Transactional
    public R<Void> update(Long id, UpdateEquipmentRequestDto dto) {
        log.info("更新设备信息，设备ID：{}，请求参数：{}", id, dto);

        // 更新读模型
        EquipmentBasicViewPo viewEntity = equipmentBasicViewService.getById(id);
        if (viewEntity != null) {
            viewEntity.setEquipmentName(dto.getEquipmentName());
            viewEntity.setManufacturer(dto.getManufacturer());
            viewEntity.setModelNumber(dto.getModelNumber());
            viewEntity.setLocation(dto.getLocation());
            equipmentBasicViewService.saveOrUpdate(viewEntity);
        }
        return R.ok("更新设备成功");
    }

    @Override
    @Transactional
    public R<Void> delete(Long id) {
        log.info("删除设备，设备ID：{}", id);

        DeleteEquipmentCommand command = DeleteEquipmentCommand.builder()
                .equipmentId(id)
                .build();

        CommandResult<Void> result = deleteCommandHandler.handle(command);
        if (!result.success()) {
            return R.fail(result.msg());
        }

        equipmentBasicViewService.removeById(id);
        return R.ok("删除设备成功");
    }

    @Override
    @Transactional
    public R<Void> batchDelete(List<Long> ids) {
        log.info("批量删除设备，设备ID列表：{}", ids);
        for (Long id : ids) {
            DeleteEquipmentCommand command = DeleteEquipmentCommand.builder()
                    .equipmentId(id)
                    .build();

            CommandResult<Void> result = deleteCommandHandler.handle(command);
            if (!result.success()) {
                return R.fail(result.msg());
            }

            equipmentBasicViewService.removeById(id);
        }
        return R.ok("批量删除设备成功");
    }
}
